package data

import (
	"errors"
	"fmt"
	"time"
)

type UserMgr struct {
	Users map[uint]*User
}

func NewUserMgr() UserMgr {
	return UserMgr{
		Users: make(map[uint]*User),
	}
}

func (this UserMgr) GetUser(id uint) *User {
	return this.Users[id]
}

func (this UserMgr) SetUser(id uint, user *User) {
	this.Users[id] = user
}

type User struct {
	Id        uint
	Uuid      string
	Name      string
	Email     string
	Pswd      string
	CreatedAt time.Time
}

type Session struct {
	Id        uint
	Uuid      string
	Email     string
	UserId    uint
	CreatedAt time.Time
}

func (this *Session) Check() (bool, error) {
	var dbSession DbSession
	Gorm.Where("uuid = ?", this.Uuid).First(&dbSession)
	if dbSession.ID == 0 {
		return false, errors.New("db no session")
	}
	this.Id = dbSession.ID
	this.Email = dbSession.Email
	this.UserId = dbSession.UserId
	this.CreatedAt = dbSession.CreatedAt
	fmt.Println("Session Check ", this)
	return true, nil
}

func (this *Session) GetUser() (User, error) {
	var dbUser DbUser
	var user User
	fmt.Println("Session get user id = ", this.UserId)
	Gorm.Where("id= ?", this.UserId).First(&dbUser)

	if dbUser.ID == 0 {
		return user, errors.New("db no user")
	}

	user.Id = dbUser.ID
	user.Uuid = dbUser.Uuid
	user.Email = dbUser.Email
	user.Name = dbUser.Name
	user.Pswd = dbUser.Pswd
	user.CreatedAt = dbUser.CreatedAt
	return user, nil
}

func (this *User) Create() (err error) {
	this.Uuid = createUUID()
	dbUser := DbUser{
		Uuid:  this.Uuid,
		Name:  this.Name,
		Email: this.Email,
		Pswd:  Encrypt(this.Pswd),
	}
	Gorm.Create(&dbUser)
	fmt.Printf("User Create, user = %+v\n", dbUser)
	return
}

func (this *User) CreateSession() (Session, error) {
	sessionUid := createUUID()
	dbSession := DbSession{
		Uuid:   sessionUid,
		Email:  this.Email,
		UserId: this.Id,
	}
	Gorm.Create(&dbSession)
	var err error
	var session Session
	if dbSession.ID == 0 {
		return session, errors.New("no session")
	}
	session.Id = dbSession.ID
	session.Uuid = dbSession.Uuid
	session.Email = dbSession.Email
	session.UserId = dbSession.UserId
	session.CreatedAt = dbSession.CreatedAt
	return session, err
}

func DelSession(uuid string) {
	fmt.Println("DelSession uuid = ", uuid)
	Gorm.Unscoped().Delete(&DbSession{}, "uuid = ?", uuid)
}

func GetUserByEmail(email string) (User, error) {
	var dbUser DbUser
	var err error = nil
	Gorm.Where("email = ?", email).First(&dbUser)
	fmt.Println("GetUserByEmail email = ", email)
	fmt.Println("GetUserByEmail dbuser = ", dbUser)
	user := User{
		Id:        dbUser.ID,
		Uuid:      dbUser.Uuid,
		Name:      dbUser.Name,
		Email:     dbUser.Email,
		Pswd:      dbUser.Pswd,
		CreatedAt: dbUser.CreatedAt,
	}
	if user.Id == 0 {
		err = errors.New("no user")
	}
	return user, err
}
